package com.rppowell.pixie.swing;

import com.rppowell.pixie.models.MapProperties;
import com.rppowell.pixie.models.PixieProject;
import com.rppowell.pixie.models.Sprite;
import com.rppowell.pixie.models.SpriteSet;
import com.rppowell.pixie.models.SpriteSetProperties;
import com.rppowell.pixie.swing.command.CommandGuiExit;
import com.rppowell.pixie.swing.command.CommandGuiImportDialog;
import com.rppowell.pixie.swing.command.CommandGuiNewMap;
import com.rppowell.pixie.swing.command.CommandGuiNewProject;
import com.rppowell.pixie.swing.command.CommandGuiNewSprite;
import com.rppowell.pixie.swing.command.CommandGuiNewSpriteSet;
import com.rppowell.pixie.swing.command.CommandGuiNewTestProject;
import com.rppowell.pixie.swing.command.CommandGuiSwitchToMapMode;
import com.rppowell.pixie.swing.command.CommandGuiSwitchToSpriteMode;
import com.rppowell.pixie.swing.importer.SpriteSetImporter;
import com.rppowell.pixie.swing.importer.SpriteSetImporterProperties;
import com.rppowell.pixie.swing.map.MapPropertiesPanel;
import com.rppowell.pixie.swing.spriteset.SpriteSetListModel;
import com.rppowell.pixie.swing.spriteset.SpriteSetPropertiesPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListModel;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public enum PixieListener implements ActionListener, ChangeListener, ListSelectionListener, WindowListener {
    INSTANCE;

    private PixieProject pixieProject;
    private PixieJFrame pixieJFrame;

    public final CommandGuiExit commandGuiExit = new CommandGuiExit();
    public final CommandGuiImportDialog commandGuiImportDialog = new CommandGuiImportDialog();
    public final CommandGuiNewProject commandGuiNewProject = new CommandGuiNewProject();
    public final CommandGuiNewTestProject commandGuiNewTestProject = new CommandGuiNewTestProject();
    public final CommandGuiNewSpriteSet commandGuiNewSpriteSet = new CommandGuiNewSpriteSet();
    public final CommandGuiNewSprite commandGuiNewSprite = new CommandGuiNewSprite();
    public final CommandGuiNewMap commandGuiNewMap = new CommandGuiNewMap();
    public final CommandGuiSwitchToSpriteMode commandGuiSwitchToSpriteMode = new CommandGuiSwitchToSpriteMode();
    public final CommandGuiSwitchToMapMode commandGuiSwitchToMapsMode = new CommandGuiSwitchToMapMode();
    
    public void setPixieProject(PixieProject p) {
        this.pixieProject = p;
    }
    public void setPixieJframe(PixieJFrame p) {
        this.pixieJFrame = p;
    }
    
    @Override
    public void valueChanged(ListSelectionEvent e) {
        // TODO PixieListener valueChanged
        System.out.println(getClass().toString() + ".valueChanged - " + e.toString());
        if (!e.getValueIsAdjusting()) {
            Object eventObject = e.getSource();
            JList jlist;
            int index;
            Object spriteSetListModelObject = null;
            SpriteSetListModel spriteSetListModel = null;
            SpriteSet spriteSet = null;
            Object spriteObject = null;
            Sprite sprite = null;
            if (eventObject instanceof JList) {
                jlist = (JList) eventObject;
                index = jlist.getSelectedIndex();             

                ListModel m = jlist.getModel();                
                if (m instanceof SpriteSetListModel) {
                    spriteSetListModel = (SpriteSetListModel)m;
                    spriteSet = spriteSetListModel.getSpriteSet();
                    spriteObject = m.getElementAt(index);
                    sprite = spriteSetListModel.getElementAt(index);
                    System.out.println(spriteSet);
                    System.out.println(sprite);
                    pixieJFrame.setSelectedSpriteInSpriteSet(spriteSet, sprite);
                }
            }
        }
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        // TODO PixieListener stateChanged
        System.out.println(getClass().toString() + ".stateChanged - " + e.toString());
    }

    @Override
    public void actionPerformed(ActionEvent actionevent) {
        System.out.println(getClass().toString() + ".actionPerformed - " + actionevent.toString());
        if (actionevent.getActionCommand().equals(this.commandGuiNewProject.getCommandString())) {
            pixieProject.resetProject();
            pixieJFrame.updateFromPixieProject(pixieProject);
        } else if (actionevent.getActionCommand().equals(this.commandGuiNewTestProject.getCommandString())) {
            try {
                pixieProject.resetToTestProject();
            } catch (Exception ex) {
                Logger.getLogger(PixieListener.class.getName()).log(Level.SEVERE, null, ex);
            }
            pixieJFrame.updateFromPixieProject(pixieProject);
        } else if (actionevent.getActionCommand().equals(this.commandGuiImportDialog.getCommandString())) {
            SpriteSetImporter importer = new SpriteSetImporter(pixieJFrame, this);
            importer.doImporterDialog();
        } else if (actionevent.getActionCommand().equals(this.commandGuiNewSpriteSet.getCommandString())) {
            SpriteSetPropertiesPanel spriteSetPropertiesPanel = new SpriteSetPropertiesPanel();

            int n = JOptionPane.showConfirmDialog(
                    pixieJFrame,
                    spriteSetPropertiesPanel,
                    "New Sprite Set",
                    JOptionPane.OK_CANCEL_OPTION);
            if (n == JOptionPane.OK_OPTION) {
                SpriteSetProperties properties = spriteSetPropertiesPanel.getSpriteSetProperties();
                pixieJFrame.doNewSpriteSet(properties);

                PixieUIState pixieUIState = pixieJFrame.getPixieUIState();
                pixieUIState.switchToSpriteMode();
                pixieJFrame.setPixieUIState(pixieUIState);
            }
        } else if (actionevent.getActionCommand().equals(this.commandGuiNewSprite.getCommandString())) {
            pixieJFrame.doNewSprite();
        } else if (actionevent.getActionCommand().equals(this.commandGuiNewMap.getCommandString())) {
            SpriteSet s = pixieJFrame.getSelectedSpriteSet();
            MapPropertiesPanel mapPropertiesPanel = new MapPropertiesPanel(s);

            int n = JOptionPane.showConfirmDialog(
                    pixieJFrame,
                    mapPropertiesPanel,
                    "New Map",
                    JOptionPane.OK_CANCEL_OPTION);
            if (n == JOptionPane.OK_OPTION) {
                MapProperties properties = mapPropertiesPanel.getMapProperties();
                pixieJFrame.doNewMap(properties);

                PixieUIState pixieUIState = pixieJFrame.getPixieUIState();
                pixieUIState.switchToMapsMode();
                pixieJFrame.setPixieUIState(pixieUIState);
            }
        } else if (actionevent.getActionCommand().equals(this.commandGuiSwitchToSpriteMode.getCommandString())) {
            PixieUIState pixieUIState = pixieJFrame.getPixieUIState();
            pixieUIState.switchToSpriteMode();
            pixieJFrame.setPixieUIState(pixieUIState);
        } else if (actionevent.getActionCommand().equals(this.commandGuiSwitchToMapsMode.getCommandString())) {
            PixieUIState pixieUIState = pixieJFrame.getPixieUIState();
            pixieUIState.switchToMapsMode();
            pixieJFrame.setPixieUIState(pixieUIState);
        } else if (actionevent.getActionCommand().equals(this.commandGuiExit.getCommandString())) {
            pixieJFrame.doWindowClosing();
        } else {
            throw new UnsupportedOperationException("Not supported yet.");
        }

    }

    public void doSpriteSetImport(SpriteSetImporterProperties properties) {
        System.out.println(getClass().toString() + ".doSpriteSetImport - " + properties);
        pixieJFrame.doSpriteSetImport(properties);
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowClosed(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        pixieJFrame.doWindowClosing();
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowOpened(WindowEvent e) {
    }
}
